package org.melanesia.beans;

import java.lang.reflect.Method;
import java.util.Map;

import org.melanesia.beans.exceptions.PropertySetException;


class MethodSetter implements Setter {

    private Method method;

    MethodSetter(Method method) {
        this.method = method;
    }
    
    @Override
    public void set(Object bean, Object value, Map<String, Class<?>> intermediateBeanClasses) {
        final boolean accessible = method.isAccessible();
        
        try {
            if (!accessible) {
                BeanUtils.setAccessible(method, true);
            }
            
            Object acceptedValue = BeanUtils.cast(value, getAcceptedType());
            method.invoke(bean, acceptedValue);
            
        } catch (Throwable t) {
            throw new PropertySetException("Error mapping bean \"" + bean.getClass() +"\". Cannot set value by calling method \"" + method.getName() + "\" accepting type \"" + getAcceptedType() + "\" with parameter \"" + value + "\" of class \"" + (value == null ? "unknown" : value.getClass()) + "\".", t);
        } finally {
            BeanUtils.setAccessible(method, accessible);
        }
    }

    @Override
    public Class<?> getAcceptedType() {
        return method.getParameterTypes()[0];
    }
}
